package com.lucifer.treasure.enchant.effect;

import com.lucifer.treasure.registry.EnchantRegistry;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents;
import net.minecraft.enchantment.EnchantmentEffectContext;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.EnchantmentLevelBasedValue;
import net.minecraft.enchantment.effect.EnchantmentEntityEffect;
import net.minecraft.entity.Entity;
import net.minecraft.entity.ExperienceOrbEntity;
import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.recipe.RecipeType;
import net.minecraft.recipe.SmeltingRecipe;
import net.minecraft.recipe.input.SingleStackRecipeInput;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;

import java.util.List;

public record AutoSmeltEnchantmentEffect(EnchantmentLevelBasedValue chance) implements EnchantmentEntityEffect {
    public static final MapCodec<AutoSmeltEnchantmentEffect> CODEC = RecordCodecBuilder.mapCodec(instance ->
            instance.group(
                    EnchantmentLevelBasedValue.CODEC.fieldOf("chance").forGetter(AutoSmeltEnchantmentEffect::chance)
            ).apply(instance, AutoSmeltEnchantmentEffect::new)
    );

    // 静态初始化方法，注册事件监听器
    public static void initialize() {
        PlayerBlockBreakEvents.AFTER.register((world, player, pos, state, blockEntity) -> {
            // 首先检查配置是否启用此附魔
            if (!EnchantRegistry.isEnchantEnabled("auto_smelt")) {
                return;
            }

            if (world.isClient() || !(player instanceof PlayerEntity)) {
                return;
            }

            ItemStack tool = player.getMainHandStack();
            if (tool.isEmpty()) {
                return;
            }

            // 检查工具是否有AutoSmelt附魔
            var enchantments = EnchantmentHelper.getEnchantments(tool);
            boolean hasAutoSmelt = false;

            for (var entry : enchantments.getEnchantments()) {
                if (entry.getKey().isPresent()) {
                    String enchantmentId = entry.getKey().get().getValue().toString();
                    if (enchantmentId.equals("lucifer_treasure:auto_smelt")) {
                        hasAutoSmelt = true;
                        break;
                    }
                }
            }

            if (!hasAutoSmelt) {
                return;
            }

            // 延迟1tick执行，确保掉落物已经生成
            world.getServer().execute(() -> {
                smeltNearbyDrops((ServerWorld) world, pos);
            });
        });
    }

    /**
     * 熔炼指定位置附近的掉落物
     */
    private static void smeltNearbyDrops(ServerWorld world, BlockPos pos) {
        // 在方块位置周围1.5格范围内查找掉落物
        List<ItemEntity> nearbyItems = world.getEntitiesByClass(ItemEntity.class,
                new net.minecraft.util.math.Box(pos).expand(1.5),
                item -> item.isAlive() && item.age < 20); // 扩大时间窗口到20ticks

        // 查找附近的玩家来检查经验提升附魔
        PlayerEntity nearestPlayer = world.getClosestPlayer(pos.getX(), pos.getY(), pos.getZ(), 8.0, false);

        for (ItemEntity itemEntity : nearbyItems) {
            ItemStack originalStack = itemEntity.getStack();
            ItemStack smeltedResult = getSmeltedResult(originalStack, world);

            if (!smeltedResult.isEmpty()) {
                // 计算并生成熔炼经验
                float smeltingExp = getSmeltingExperience(originalStack, world);
                if (smeltingExp > 0) {
                    int totalExp = Math.round(smeltingExp * originalStack.getCount());

                    // 如果玩家有经验提升附魔，增加熔炼经验
                    if (nearestPlayer != null) {
                        ItemStack tool = nearestPlayer.getMainHandStack();
                        if (!tool.isEmpty()) {
                            var enchantments = EnchantmentHelper.getEnchantments(tool);
                            for (var entry : enchantments.getEnchantments()) {
                                if (entry.getKey().isPresent()) {
                                    String enchantmentId = entry.getKey().get().getValue().toString();
                                    if (enchantmentId.equals("lucifer_treasure:experience_boost")) {
                                        int level = enchantments.getLevel(entry);
                                        // 大幅增强熔炼经验倍数
                                        // 基础倍数：10倍熔炼经验 + 经验提升等级的额外加成
                                        double baseMultiplier = 10.0; // 基础10倍经验
                                        // 应用经验提升：每级增加3倍经验，开平方提供递减收益
                                        double levelMultiplier = (level * 3.0) + Math.sqrt(level * 5.0);
                                        double finalMultiplier = baseMultiplier + levelMultiplier;
                                        totalExp = (int) Math.round(totalExp * finalMultiplier);
                                        break;
                                    }
                                }
                            }
                        }
                    } else {
                        // 即使没有经验提升附魔，自动熔炼本身也给予5倍基础经验
                        totalExp = Math.round(totalExp * 5.0f);
                    }

                    if (totalExp > 0) {
                        // 生成经验球
                        ExperienceOrbEntity expOrb = new ExperienceOrbEntity(
                                world,
                                itemEntity.getX(),
                                itemEntity.getY() + 0.3,
                                itemEntity.getZ(),
                                totalExp
                        );
                        world.spawnEntity(expOrb);
                    }
                }

                // 替换掉落物为熔炼后的物品
                itemEntity.setStack(smeltedResult);

                // 添加熔炼粒子效果
                world.spawnParticles(
                        net.minecraft.particle.ParticleTypes.FLAME,
                        itemEntity.getX(), itemEntity.getY() + 0.2, itemEntity.getZ(),
                        5, 0.2, 0.2, 0.2, 0.05
                );

                // 添加经验粒子效果
                if (smeltingExp > 0) {
                    world.spawnParticles(
                            net.minecraft.particle.ParticleTypes.HAPPY_VILLAGER,
                            itemEntity.getX(), itemEntity.getY() + 0.3, itemEntity.getZ(),
                            3, 0.3, 0.1, 0.3, 0.1
                    );
                }
            }
        }
    }

    @Override
    public void apply(ServerWorld world, int level, EnchantmentEffectContext context, Entity target, Vec3d pos) {
        // 逻辑在事件监听器中处理
    }

    private static ItemStack getSmeltedResult(ItemStack input, ServerWorld world) {
        if (input.isEmpty()) {
            return ItemStack.EMPTY;
        }

        SingleStackRecipeInput recipeInput = new SingleStackRecipeInput(input);
        var recipeOptional = world.getRecipeManager().getFirstMatch(RecipeType.SMELTING, recipeInput, world);

        if (recipeOptional.isPresent()) {
            var recipe = recipeOptional.get();
            ItemStack result = recipe.value().craft(recipeInput, world.getRegistryManager());
            result.setCount(input.getCount()); // 保持原有数量
            return result;
        }

        return ItemStack.EMPTY;
    }

    /**
     * 获取熔炼配方的经验值
     *
     * @param itemStack 输入物品
     * @param world     世界
     * @return 熔炼经验值
     */
    private static float getSmeltingExperience(ItemStack itemStack, ServerWorld world) {
        if (itemStack.isEmpty()) {
            return 0.0f;
        }

        SingleStackRecipeInput recipeInput = new SingleStackRecipeInput(itemStack);
        var recipeOptional = world.getRecipeManager().getFirstMatch(RecipeType.SMELTING, recipeInput, world);

        if (recipeOptional.isPresent()) {
            var recipe = recipeOptional.get();
            if (recipe.value() instanceof SmeltingRecipe smeltingRecipe) {
                return smeltingRecipe.getExperience();
            }
        }

        return 0.0f;
    }

    @Override
    public MapCodec<? extends EnchantmentEntityEffect> getCodec() {
        return CODEC;
    }
} 